<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ESP32C3 Supermini功能配置</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
        }

        .container {
            width: 350px;
            margin: 0 auto;
            padding: 10px 10px 10px 10px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        .mode-selection {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
        }

        .mode-option {
            display: flex;
            align-items: center;
        }

        .form-container {
            background-color: #f5f5f5;
            padding: 10px;
            border-radius: 8px;
        }

        .row-group {
            margin-bottom: 15px;
            display: flex;
            align-items: center;
        }

        .row-group label {
            min-width: 70px;
            margin-right: 0px;
        }

        input[type="radio"] {
            padding: 8px;
            margin-right: 0px;
            box-sizing: border-box;
        }

        .hidden {
            display: none;
        }

        .error-message {
            color: red;
            font-size: 12px;
            margin-left: 4px;
            display: none;
        }

        input[type="text"] {
            flex-grow: 1;
            padding: 8px;
            box-sizing: border-box;
        }

        textarea {
            width: 100%;
            padding: 8px;
            box-sizing: border-box;
            min-height: 238px;
            resize: vertical;
        }

        .time-container {
            border: 1px solid #000000;
        }

        .time-container-top {
            border-bottom: 1px solid #000000;
        }

        .time-container-top label {
            display: block;
            text-align: center;
            margin: 10px 0px;
        }

        .time-container-fill {
            height: 130px;
            overflow-y: scroll;
            flex-direction: column-reverse;
            padding: 10px;

        }

        .time-slot {
            display: flex;
            align-items: center;
            padding: 12px;
            border: 1px solid #ddd;
            border-radius: 6px;
            margin-bottom: 10px;
            background: #f9f9f9;
        }

        .time-slot.selected {
            background: #e6f2ff;
            border-color: #b3d1ff;
        }

        .time-input {
            padding: 8px;
            border: 1px solid #ccc;
            border-radius: 4px;
            margin: 0 10px;
        }

        .btn {
            padding: 5px 10px;
            height: 36px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-weight: bold;
            transition: background 0.3s;
        }

        .btn-group {
            display: flex;
            gap: 10px;
            margin-top: 10px;
        }

        .btn-add {
            background: #4a89dc;
            color: white;
        }

        .btn-deleteSelected {
            background: #f39c12;
            color: white;
        }

        .btn-deleteAll {
            background: #e74c3c;
            color: white;
        }

        .spinner {
            display: none;
            min-width: 30px;
            width: 30px;
            height: 30px;
            margin-right: 10px;
            border: 4px solid rgba(0, 0, 0, 0.1);
            border-radius: 50%;
            border-top: 4px solid #28a745;
            animation: spin 1s linear infinite;
        }

        @keyframes spin {
            0% {
                transform: rotate(0deg);
            }

            100% {
                transform: rotate(360deg);
            }
        }

        .status {
            flex: 1;
            height: auto;
            font-size: small;
            white-space: pre-line;
        }

        .success {
            color: #155724;
        }

        .information {
            color: #4a89dc;
        }

        .warning {
            color: #efb41f;
        }

        .error {
            color: #721c24;
        }

        .btn-save {
            background: #2ecc71;
            color: white;
        }

        .btn-load {
            background: #95a5a6;
            color: white;
        }

        .btn-reset {
            background: #e74c3c;
            color: white;
        }

        .btn-restart {
            background: #f39c12;
            color: white;
        }
    </style>
</head>

<body>
    <div class="container">
        <h1 style="text-align: center;margin-top: 0px; margin-bottom: 10px;">功能配置</h1>
        <div class="mode-selection">
            <div class="mode-option">
                <label><input type="radio" name="runMode" value="STATIC" checked> 静态模式</label>
            </div>
            <div class="mode-option">
                <label><input type="radio" name="runMode" value="DYNAMIC_MASTER"> 动态主机模式</label>
            </div>
            <div class="mode-option">
                <label><input type="radio" name="runMode" value="DYNAMIC_SLAVE"> 动态从机模式</label>
            </div>
        </div>

        <div class="form-container">
            <div class="row-group">
                <label>MAC:</label>
                <input type="text" id="mac" name="mac" placeholder="A1:B2:C3:D4:E5:F6">
                <div id="macError" class="error-message">请输入有效的MAC地址！</div>
            </div>
            <div class="row-group" id="staticFields">
                <label>RAW:</label>
                <textarea id="raw" name="raw"></textarea>
            </div>

            <div id="dynamicFields" class="hidden">
                <div class="row-group">
                    <label>SSID:</label>
                    <input type="text" id="ssid" name="ssid">
                </div>
                <div class="row-group">
                    <label>Pwd:</label>
                    <input type="text" id="password" name="password">
                </div>
                <div class="row-group">
                    <label>APPID:</label>
                    <input type="text" id="appId" name="appId">
                </div>
                <div class="row-group">
                    <label>APPKey:</label>
                    <input type="text" id="appKey" name="appKey">
                </div>
                <div class="row-group">
                    <label>APIURL:</label>
                    <input type="text" id="apiUrl" name="apiUrl">
                </div>
            </div>

            <div id="timePeriodFields" class="time-container hidden">
                <div class="time-container-top">
                    <label>开启时间段配置</label>
                </div>
                <div id="timePeriodDiv" class="time-container-fill">
                    <div class="time-slots" id="timeSlots"></div>
                    <div class="btn-group">
                        <button class="btn btn-add" id="addBtn">添加时段</button>
                        <button class="btn btn-deleteSelected" id="deleteSelectedBtn">删除所选</button>
                        <button class="btn btn-deleteAll" id="deleteAllBtn">删除全部</button>
                    </div>
                </div>
            </div>

        </div>

        <div style="display: flex;background-color: #f5f5f5;border-radius: 8px;margin-top: 10px;padding: 10px;height: 40px;">
            <div class="spinner" id="spinner"></div>
            <div class="status" id="status"></div>
        </div>

        <div class="btn-group">
            <button class="btn btn-save" id="saveBtn">保存配置</button>
            <button class="btn btn-load" id="loadBtn">读取配置</button>
            <button class="btn btn-reset" id="resetBtn">重置设备</button>
            <button class="btn btn-restart" id="restartBtn">重启设备</button>
        </div>

    </div>

    <script>
        // document.addEventListener('DOMContentLoaded', function () { });

        // 动态主机开启时间段配置，添加时自动滚动到最下方
        const timePeriodDiv = document.getElementById('timePeriodDiv');
        const observer = new MutationObserver(() => {
            timePeriodDiv.scrollTop = timePeriodDiv.scrollHeight;
        });
        observer.observe(timePeriodDiv, { childList: true, subtree: true });

        // MAC地址验证函数
        function validateMacAddress(mac) {
            const macRegex = /^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$/;
            return macRegex.test(mac);
        }

        // 监听MAC地址输入变化
        const macInput = document.getElementById('mac');
        const macError = document.getElementById('macError');
        macInput.addEventListener('input', function () {
            const macValue = this.value.trim();
            if (macValue && !validateMacAddress(macValue)) {
                this.classList.add('error');
                macError.style.display = 'block';
            } else {
                this.classList.remove('error');
                macError.style.display = 'none';
            }
        });

        //点击不同运行模式，显示不同页面
        const runModeRadios = document.querySelectorAll('input[name="runMode"]');
        const staticFields = document.getElementById('staticFields');
        const dynamicFields = document.getElementById('dynamicFields');
        const timePeriodFields = document.getElementById('timePeriodFields');
        runModeRadios.forEach(radio => {
            radio.addEventListener('change', function () {
                if (this.value === 'STATIC') {
                    staticFields.classList.remove('hidden');
                    dynamicFields.classList.add('hidden');
                    timePeriodFields.classList.add('hidden');
                } else {
                    staticFields.classList.add('hidden');
                    dynamicFields.classList.remove('hidden');
                    if (this.value === 'DYNAMIC_MASTER') {
                        timePeriodFields.classList.remove('hidden');
                    }
                    else {
                        timePeriodFields.classList.add('hidden');
                    }
                }
            });
        });

        // 时段配置数据结构
        let timeSlots = [];

        // 添加新时段
        const timeSlotsContainer = document.getElementById('timeSlots');
        const addBtn = document.getElementById('addBtn');
        addBtn.addEventListener('click', () => {
            const newSlot = {
                id: Date.now(),
                start: '07:00',
                end: '19:00',
                selected: false
            };
            timeSlots.push(newSlot);
            renderTimeSlots();
        });

        // 删除所选时段
        const deleteSelectedBtn = document.getElementById('deleteSelectedBtn');
        deleteSelectedBtn.addEventListener('click', () => {
            if (timeSlots.some(slot => slot.selected)) {
                timeSlots = timeSlots.filter(slot => !slot.selected);
                renderTimeSlots();
                showStatus('已删除选中的时段', 'success');
            } else {
                showStatus('请先选择要删除的时段', 'error');
            }
        });

        // 删除全部时段
        const deleteAllBtn = document.getElementById('deleteAllBtn');
        deleteAllBtn.addEventListener('click', () => {
            if (timeSlots.length > 0) {
                timeSlots = [];
                renderTimeSlots();
                showStatus('已删除全部时段配置', 'success');
            } else {
                showStatus('当前没有可删除的时段', 'error');
            }
        });

        // 渲染时段列表
        function renderTimeSlots() {
            timeSlotsContainer.innerHTML = timeSlots.map(slot => `
                <div class="time-slot ${slot.selected ? 'selected' : ''}" data-id="${slot.id}">
                    <input type="checkbox" ${slot.selected ? 'checked' : ''} 
                           class="toggle-select">
                    <input type="time" value="${slot.start}" 
                           class="time-input start-time">
                    <span>至</span>
                    <input type="time" value="${slot.end}" 
                           class="time-input end-time">
                </div>
            `).join('');

            // 绑定事件
            document.querySelectorAll('.toggle-select').forEach(checkbox => {
                checkbox.addEventListener('change', (e) => {
                    const id = parseInt(e.target.closest('[data-id]').dataset.id);
                    const slot = timeSlots.find(s => s.id === id);
                    if (slot) {
                        slot.selected = e.target.checked;
                        e.target.closest('.time-slot').classList.toggle('selected');
                    }
                });
            });

            document.querySelectorAll('.start-time, .end-time').forEach(input => {
                input.addEventListener('change', (e) => {
                    const id = parseInt(e.target.closest('[data-id]').dataset.id);
                    const slot = timeSlots.find(s => s.id === id);
                    if (slot) {
                        const field = e.target.classList.contains('start-time') ? 'start' : 'end';
                        slot[field] = e.target.value;
                    }
                });
            });
        }

        // 保存配置到ESP32
        const saveBtn = document.getElementById('saveBtn');
        saveBtn.addEventListener('click', async () => {
            // 禁用按钮并显示加载动画
            saveBtn.disabled = true;
            spinner.style.display = 'block';

            const runMode = document.querySelector('input[name="runMode"]:checked').value;
            const mac = document.getElementById('mac').value;
            const raw = document.getElementById('raw').value;
            const ssid = document.getElementById('ssid').value;
            const password = document.getElementById('password').value;
            const appId = document.getElementById('appId').value;
            const appKey = document.getElementById('appKey').value;
            const apiUrl = document.getElementById('apiUrl').value;

            let isValid = true;
            let errorStr = '';

            // 验证数据
            if (!validateMacAddress(mac.trim())) {
                errorStr += "mac地址格式错误；\n";
                isValid = false;
            }

            if (runMode === 'STATIC') {
                if (!raw.trim()) {
                    errorStr += "raw不能为空；\n";
                    isValid = false;
                }
            }
            else {
                if (!ssid.trim()) {
                    errorStr += "ssid不能为空；\n";
                    isValid = false;
                }
                if (!password.trim()) {
                    errorStr += "password不能为空；\n";
                    isValid = false;
                }
                if (!appId.trim()) {
                    errorStr += "appId不能为空；\n";
                    isValid = false;
                }
                if (!appKey.trim()) {
                    errorStr += "appKey不能为空；\n";
                    isValid = false;
                }
                if (!apiUrl.trim()) {
                    errorStr += "apiUrl不能为空；\n"
                    isValid = false;
                }
            }

            if (!isValid) {
                showStatus(errorStr, "error");
                // 恢复按钮状态
                saveBtn.disabled = false;
                spinner.style.display = 'none';
                return;
            }


            let config;
            let configInfo = '保存配置如下:';
            // 构建配置对象
            if (runMode === 'STATIC') {
                config = {
                    runMode: runMode,
                    mac: mac.toUpperCase(),
                    raw: raw
                };
                configInfo +=`\nrunMode：${config.runMode}；`;
                configInfo +=`\nmac：${config.mac}；`;
                configInfo +=`\nraw：${config.raw}；`;
            }
            else if (runMode === 'DYNAMIC_MASTER') {
                config = {
                    runMode: runMode,
                    mac: mac.toUpperCase(),
                    ssid: ssid,
                    password: password,
                    appId: appId,
                    appKey: appKey,
                    apiUrl: apiUrl,
                    sendPeriods: timeSlots
                };
                configInfo +=`\nrunMode：${config.runMode}；`;
                configInfo +=`\nmac：${config.mac}；`;
                configInfo +=`\nssid：${config.ssid}；`;
                configInfo +=`\npassword：${config.password}；`;
                configInfo +=`\nappId：${config.appId}；`;
                configInfo +=`\nappKey：${config.appKey}；`;
                configInfo +=`\napiUrl：${config.apiUrl}；`;
                timeSlots.forEach((slot, index) => {
                    configInfo += `\n开启时段${index + 1}: ${slot.start}-${slot.end}`;
                });
            }
            else if (runMode === 'DYNAMIC_SLAVE') {
                config = {
                    runMode: runMode,
                    mac: mac.toUpperCase(),
                    ssid: ssid,
                    password: password,
                    appId: appId,
                    appKey: appKey,
                    apiUrl: apiUrl
                };
                configInfo +=`\nrunMode：${config.runMode}；`;
                configInfo +=`\nmac：${config.mac}；`;
                configInfo +=`\nssid：${config.ssid}；`;
                configInfo +=`\npassword：${config.password}；`;
                configInfo +=`\nappId：${config.appId}；`;
                configInfo +=`\nappKey：${config.appKey}；`;
                configInfo +=`\napiUrl：${config.apiUrl}；`;
            }

            showStatus(configInfo, 'information');

            // 发送请求到后台
            try {
                const response = await fetch('/api/save', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(config)
                });

                if (!response.ok) {
                    const errorData = await response.text();
                    try {// 尝试解析错误响应为JSON       
                        const jsonError = JSON.parse(errorData);
                        throw new Error(jsonError.error || '请求失败');
                    } catch {// 非JSON格式的错误响应       
                        throw new Error(errorData || `HTTP ${response.status}`);
                    }
                }
                else {
                    showStatus('配置已成功保存，2秒后自动重启设备', 'success');
                    // 模拟设备重启过程
                    const text = await response.text();
                    showRestartNotification(text, 2000);
                }
            } catch (error) {
                showStatus('保存失败: ' + error.message, 'error');
            }
            finally {
                // 恢复按钮状态
                saveBtn.disabled = false;
                spinner.style.display = 'none';
            }
        });

        // 从ESP32加载配置
        const loadBtn = document.getElementById('loadBtn');
        loadBtn.addEventListener('click', async () => {
            // 禁用按钮并显示加载动画
            loadBtn.disabled = true;
            spinner.style.display = 'block';
            showStatus('正在加载配置...', 'warning');

            try {
                // 从后端获取配置数据
                const response = await fetch('/api/load');
                if (!response.ok) {
                    throw new Error('获取配置失败');
                }
                const config = await response.json();

                // 设置运行模式并触发事件
                const runModeRadios = document.getElementsByName('runMode');
                for (const radio of runModeRadios) {
                    if (radio.value === config.runMode) {
                        radio.checked = true;
                        // 创建并触发change事件
                        const event = new Event('change', {
                            bubbles: true,
                            cancelable: true
                        });
                        radio.dispatchEvent(event);
                        break;
                    }
                }

                if (config.runMode === "NOSET") {
                    showStatus('设备暂无配置，请在此网页进行配置', 'information');
                }
                else if (config.runMode === "STATIC") {
                    // 处理静态模式
                    document.getElementById('mac').value = config.mac || '';
                    document.getElementById('raw').value = config.raw || '';
                    showStatus('配置已从ESP32加载', 'success');
                }
                else {
                    // 处理动态主机模式和动态从机模式
                    document.getElementById('mac').value = config.mac || '';
                    document.getElementById('raw').value = config.raw || '';
                    document.getElementById('ssid').value = config.ssid || '';
                    document.getElementById('password').value = config.password || '';
                    document.getElementById('appId').value = config.appId || '';
                    document.getElementById('appKey').value = config.appKey || '';
                    document.getElementById('apiUrl').value = config.apiUrl || '';

                    if (config.runMode === "DYNAMIC_MASTER") {
                        // 处理时间段配置
                        timeSlots = config.sendPeriods.map(period => ({
                            id: Date.now(), // 生成唯一ID       
                            start: period.start || '08:00', // 默认值       
                            end: period.end || '17:00', // 默认值
                            selected: false // 初始化选择状态     
                        }));
                        renderTimeSlots();
                    }
                    showStatus('配置已从ESP32加载', 'success');
                }
            }
            catch (error) {
                showStatus(error.message, 'error');
            }
            finally {
                // 恢复按钮状态
                loadBtn.disabled = false;
                spinner.style.display = 'none';
            }
        });

        // 重置设备按钮
        const resetBtn = document.getElementById('resetBtn');
        resetBtn.addEventListener('click', async () => {
            const userConfirmed = confirm("重置设备将会清空设备配置，您确定要重置设备吗？");
            if (!userConfirmed) {
                showStatus('取消重置设备', 'information');
                return;
            }

            // 禁用按钮并显示加载动画
            resetBtn.disabled = true;
            spinner.style.display = 'block';
            showStatus('正在重置设备...', 'warning');

            try {
                const response = await fetch('/api/reset', {
                    method: 'POST'
                });
                if (!response.ok) {
                    throw new Error('重置设备请求失败');
                }
                else {
                    showStatus('重置设备请求成功，2秒后自动重启设备', 'success');
                    // 模拟设备重启过程
                    const text = await response.text();
                    showRestartNotification(text, 2000);
                }
            }
            catch (error) {
                showStatus(error.message, 'error');
            }
            finally {
                // 恢复按钮状态
                resetBtn.disabled = false;
                spinner.style.display = 'none';
            }
        });

        // 重启设备按钮
        const restartBtn = document.getElementById('restartBtn');
        restartBtn.addEventListener('click', async () => {
            // 禁用按钮并显示加载动画
            restartBtn.disabled = true;
            spinner.style.display = 'block';
            showStatus('正在重启设备...', 'warning');

            try {
                const response = await fetch('/api/restart', {
                    method: 'POST'
                });
                if (!response.ok) {
                    throw new Error('重启设备请求失败');
                }
                else {
                    showStatus('重启设备请求成功，2秒后自动重启设备', 'success');
                    // 模拟设备重启过程
                    const text = await response.text();
                    showRestartNotification(text, 2000);
                }
            }
            catch (error) {
                showStatus(error.message, 'error');
            }
            finally {
                // 恢复按钮状态
                restartBtn.disabled = false;
                spinner.style.display = 'none';
            }
        });

        // 显示状态信息
        const statusEl = document.getElementById('status');
        function showStatus(message, type) {
            statusEl.className = `status ${type}`;
            statusEl.textContent = `${type}: ${message}`;
        }

        //保存配置、重置设备、重启设备后进入重启HTML页面
        function showRestartNotification(text, delay = 2000) {
            setTimeout(() => {
                document.write(`
                <!DOCTYPE html>
                <html lang="zh-CN">
                <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>设备重启中</title>
                <style>
                    body {
                        margin: 0;
                        padding: 0;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        height: 100vh;
                        background-color: #f0f2f5;
                        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
                    }

                    .restart-container {
                        text-align: center;
                        padding: 2rem;
                        border-radius: 8px;
                        background-color: white;
                        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
                        max-width: 350px;
                        width: 90%;
                    }

                    .restart-message {
                        font-size: 1.5rem;
                        color: #333;
                        margin-bottom: 1rem;
                    }

                    .spinner {
                        border: 4px solid rgba(0, 0, 0, 0.1);
                        border-radius: 50%;
                        border-top: 4px solid #3498db;
                        width: 40px;
                        height: 40px;
                        animation: spin 1s linear infinite;
                        margin: 0 auto;
                    }

                    @keyframes spin {
                        0% { transform: rotate(0deg); }
                        100% { transform: rotate(360deg); }
                    }
                </style>
                </head>
                <body>
                    <div class="restart-container">
                    <div class="restart-message">${text}</div>
                    <div class="spinner"></div>
                </div>
                </body>
                </html>
        `);
            }, delay);
        }

        // 初始化
        renderTimeSlots();
    </script>
</body>

</html>